package com.heima.search.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.model.common.dtos.PageResponseResult;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.search.dtos.UserSearchDto;
import com.heima.model.search.pojos.ApAssociateWords;
import com.heima.search.mapper.ApAssociateWordsMapper;
import com.heima.search.model.Trie;
import com.heima.search.service.ApAssociateWordsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class ApAssociateWordsServiceImpl extends ServiceImpl<ApAssociateWordsMapper, ApAssociateWords> implements ApAssociateWordsService {


    /**
     * 查询联想词
     * @param dto
     * @return
     */
    @Override
    public ResponseResult search(UserSearchDto dto) {
        //检查参数
        if (dto==null||dto.getSearchWords()==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        dto.getFromIndex();
        if (dto.getPageSize()>50){
            dto.setPageSize(20);
        }

        LambdaQueryWrapper<ApAssociateWords> wrapper = Wrappers.<ApAssociateWords>lambdaQuery();
        //根据时间查询
        wrapper.ge(StringUtils.isNotEmpty(dto.getMinBehotTime().toString()),ApAssociateWords::getCreatedTime,dto.getMinBehotTime());

        //模糊查询
        wrapper.like(ApAssociateWords::getAssociateWords,dto.getSearchWords());
        //排序条件
        wrapper.orderByDesc(ApAssociateWords::getCreatedTime);

        Page<ApAssociateWords> page1=new Page<>(0,dto.getPageSize());
        //分页查询
        IPage<ApAssociateWords> page = page(page1, wrapper);

        //返回参数
        PageResponseResult result=new PageResponseResult(0,(int)page.getSize(),(int)page.getTotal());
        result.setData(page.getRecords());
        return result;
    }


    @Autowired
    RedisTemplate redisTemplate;
    /**
     * 查询联想词,用redis优化
     * @param dto
     * @return
     */
    @Override
    public ResponseResult searchV2(UserSearchDto dto) {
     //检查数据
        if (dto==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
      //从redis中查询缓存数据
        String associate_list = (String) redisTemplate.opsForValue().get("associate_list");

        List<ApAssociateWords> associateWordsList=null;
        //如果查询到数据则返回
        if (StringUtils.isNotEmpty(associate_list)){
          associateWordsList=  JSON.parseArray(associate_list,ApAssociateWords.class);
         //   return ResponseResult.okResult(associateWordsList);
        }else {
            //如果没有查询到则查询数据ku
            associateWordsList = list();
            if (associateWordsList==null||associateWordsList.size()==0){
                //如果没有查询到则保存一个空值到redis中，并返回一个空值
                return ResponseResult.okResult(associateWordsList);
            }
            //redis中如果保存缓存失败要进行捕捉，不能影响返回结果
            try {
                //如果在数据库中查询到数据保存到redis中并返回
                redisTemplate.opsForValue().set("associate_list",associateWordsList);
            } catch (Exception e) {

                e.printStackTrace();
            }
        }

        Trie trie = new Trie();
        List<String> collect = associateWordsList.stream().map(apAssociateWords -> apAssociateWords.getAssociateWords()).collect(Collectors.toList());
        trie.insert(collect);
        List<String> list = trie.startWith(dto.getSearchWords());
        List<ApAssociateWords> associateWords=new ArrayList<>();
        for (String s : list) {
            ApAssociateWords words=new ApAssociateWords();
            words.setAssociateWords(s);
            associateWords.add(words);
        }

        return ResponseResult.okResult(associateWords);
    }


}
